#include <iostream>
#include <string>

class Prototype
{
public:
    virtual ~Prototype() {}

    virtual Prototype *clone() = 0;
    virtual std::string type() = 0;
};

class ConcretePrototypeA : public Prototype
{
public:
    ~ConcretePrototypeA() {}

    Prototype *clone()
    {
        return new ConcretePrototypeA();
    }

    std::string type()
    {
        return "type A";
    }
};

class ConcretePrototypeB : public Prototype
{
public:
    ~ConcretePrototypeB() {}

    Prototype *clone()
    {
        return new ConcretePrototypeB();
    }

    std::string type()
    {
        return "type B";
    }
};

class Client
{
public:
    static void init()
    {
        types_[0] = new ConcretePrototypeA;
        types_[1] = new ConcretePrototypeB;
    }

    static void finit()
    {
        delete types_[0];
        delete types_[1];
    }

    static Prototype *make(const int index)
    {
        if (index < 0 || index >= n_types)
            return nullptr;

        return types_[index]->clone();
    }

private:
    static Prototype *types_[2];
    static int n_types;
};

// 类的静态变量，需要在class声明之外的地方独立初始化：
Prototype *Client::types_[2];
int Client::n_types = 2;

int main()
{
    Client::init();

    Prototype *p1 = Client::make(0);
    std::cout << "1st prototype: " << p1->type() << std::endl;
    delete p1;

    Prototype *p2 = Client::make(1);
    std::cout << "2st prototype: " << p2->type() << std::endl;
    delete p2;

    Client::finit();

    return 0;
}